/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.editor;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.filechooser.FileFilter;

import twaver.Card;
import twaver.Element;
import twaver.Link;
import twaver.PopupMenuGenerator;
import twaver.ResizableNode;
import twaver.Shelf;
import twaver.Slot;
import twaver.TView;
import twaver.TWaverUtil;
import twaver.network.TNetwork;
import twaver.network.action.AlignBottomAction;
import twaver.network.action.AlignCenterAction;
import twaver.network.action.AlignLeftAction;
import twaver.network.action.AlignMiddleAction;
import twaver.network.action.AlignRightAction;
import twaver.network.action.AlignTopAction;
import twaver.network.action.BottomPileAction;
import twaver.network.action.ClearDataBoxAction;
import twaver.network.action.CopyAction;
import twaver.network.action.EvenHSpaceAction;
import twaver.network.action.EvenVSpaceAction;
import twaver.network.action.LeftPileAction;
import twaver.network.action.MoveFirstAction;
import twaver.network.action.MoveLastAction;
import twaver.network.action.PasteAction;
import twaver.network.action.RightPileAction;
import twaver.network.action.SameHeightAction;
import twaver.network.action.SameWidthAction;
import twaver.network.action.TopPileAction;
import twaver.network.background.ColorBackground;

/**
 * This this default popup menu factory for editable network.
 * It provides the familiar menus for editable network, like
 * align location, event space, move the layer etc.
 */
public class EditablePopupMenuGenerator implements PopupMenuGenerator {
    private TNetwork network = null;

    /**
     * Constructs the menu factory by given network.
     * @param network the network component.
     */
    public EditablePopupMenuGenerator(TNetwork network) {
        this.network = network;
    }

    public JPopupMenu generate(TView tview, MouseEvent mouseEvent) {
         JPopupMenu popMenu = new JPopupMenu();
         JMenuItem item;
         
         popMenu.add(new ClearDataBoxAction(network));
         
         //if select nothing
         if (network.getDataBox().getSelectionModel().size() == 0) {
             item = new JMenuItem("Save SubNetwork");
             item.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					JFileChooser chooser = new JFileChooser();
			        chooser.setFileFilter(new FileFilter() {
			            public boolean accept(File f) {
			                return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
			            }
			            public String getDescription() {
			                return "XML File";
			            }
			        });
                    int returnVal = chooser.showSaveDialog(network);
                    if (returnVal != JFileChooser.APPROVE_OPTION) {
                        return;
                    }
                    String fileName = chooser.getSelectedFile().getAbsolutePath();
                    try {
						network.saveCurrentSubNetwork(fileName, false, true);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
             });
             popMenu.add(item);
         } else {
             popMenu.add(getLayerMenu());
             popMenu.add(getAlignMenu());
             popMenu.add(getEvenSpaceMenu());
             popMenu.add(getPileMenu());
             popMenu.add(getSameSizeMenu());

             item=new JMenuItem("Reset Default Size");
             item.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    Iterator it=network.getSelectionModel().getAllSelectedElement().iterator();
                    while(it.hasNext()){
                        Element element=(Element)it.next();
                        if(element instanceof ResizableNode){
                            if(element.getImage()!=null){
                                int width=element.getImage().getIconWidth();
                                int height=element.getImage().getIconHeight();
                                ( (ResizableNode) element).setSize(width,height);
                            }
                        }
                    }
                }
            });
            popMenu.add(item);

             popMenu.addSeparator();
             //copy menu.
             popMenu.add(new CopyAction(network));
         }

         popMenu.add(new PasteAction(network));

     	 if(network.getDataBox().getSelectionModel().size() == 1){
     		 final Element element = network.getDataBox().getLastSelectedElement();

             item = new JMenuItem("Edit Label");
             popMenu.add(item);
             item.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					 Element element = network.getDataBox().getLastSelectedElement();
					 network.startEditingAtElement(element);
				}
             });

             item = new JMenuItem("Deep Clone");
             popMenu.add(item);
             item.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					 Element element = network.getDataBox().getLastSelectedElement();
		     		 element = TWaverUtil.cloneElement(element, false);
		     		 network.getDataBox().addElementWithDescendant(element);
		     		 if(element instanceof Link){
		     			 Link link = (Link)element;
		     			 network.getDataBox().addElement((link.getFrom()));
		     			 network.getDataBox().addElement((link.getTo()));
		     		 }
				}
             });
             
             if(element instanceof Slot){
            	 item = new JMenuItem("Adjust Slot Bounds");
                 popMenu.add(item);
                 item.addActionListener(new ActionListener(){
    				public void actionPerformed(ActionEvent e) {
    		     		 ((Slot)element).adjustBounds();
    				}
                 });
             }

             if(element instanceof Card){
            	 item = new JMenuItem("Adjust Card Bounds");
                 popMenu.add(item);
                 item.addActionListener(new ActionListener(){
    				public void actionPerformed(ActionEvent e) {
    		     		 ((Card)element).adjustBounds();
    				}
                 });
             }

             if(element instanceof Shelf){
            	 item = new JMenuItem("Adjust Shelf Bounds");
                 popMenu.add(item);
                 item.addActionListener(new ActionListener(){
    				public void actionPerformed(ActionEvent e) {
    		     		 ((Shelf)element).adjustBounds();
    				}
                 });
             }
    	 }

         popMenu.addSeparator();
         item = new JMenuItem("Background Color");
         popMenu.add(item);
         item.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 Color color = JColorChooser.showDialog(network, "Pick Color",
                     Color.white);
                 if (color != null) {
                	 network.setCurrentBackground(new ColorBackground(color)); 
                 }
             }
         });

         return popMenu;
     }

    /**
     * Get the align menus.
     * @return the align menus.
     */
    private JMenu getAlignMenu() {
        JMenu menu = new JMenu("Align");
        menu.add(new AlignLeftAction(network));
        menu.add(new AlignCenterAction(network));
        menu.add(new AlignRightAction(network));
        menu.addSeparator();
        menu.add(new AlignTopAction(network));
        menu.add(new AlignMiddleAction(network));
        menu.add(new AlignBottomAction(network));
        return menu;
    }

    /**
     * Get the even space menu.
     * @return the even space menu.
     */
    private JMenu getEvenSpaceMenu() {
        JMenu menu = new JMenu("Even Space");
        menu.add(new EvenHSpaceAction(network));
        menu.add(new EvenVSpaceAction(network));
        return menu;
    }

    private JMenu getPileMenu() {
        JMenu menu = new JMenu("Pile up");
        menu.add(new LeftPileAction(network));
        menu.add(new RightPileAction(network));
        menu.add(new TopPileAction(network));
        menu.add(new BottomPileAction(network));
        return menu;
    }


    /**
     * Get the same size menus.
     * @return the same size menus.
     */
    private JMenu getSameSizeMenu() {
        JMenu menu = new JMenu("Same Size");
        menu.add(new SameWidthAction(network));
        menu.add(new SameHeightAction(network));
        return menu;
    }

    /**
     * Get the change layer menus.
     * @return the change layer menus.
     */
    private JMenu getLayerMenu() {
        JMenu menu = new JMenu("Layer");
        menu.add(new MoveFirstAction(network));
        menu.add(new MoveLastAction(network));
        return menu;
    }
}